<?php
/**
 * Custom Application User class
 *
 * @author Xavier VILAIN
 * 
 * @method array mailboxExcludingRules()
 */
use Fox\Dao\SqlFragment;
use Doctrine\DBAL\Types\Type;
use Hive\Ressource;
use Doctrine\DBAL\Connection;

class User extends \Fox\User
{
	/**
	 *
	 * Limit base on the assigned authorisation
	 * to limit status list
	 *
	 * @var string
	 */
	const LIMIT_STATUS = "status";

	/**
	 * Mailbox excluding rules
	 * @var string
	 */
	const LINK_MAILBOX_EXCLUDING_RULES = 'mailboxExcludingRules';
	
	/**
	 * Defaut date format to us date
	 * @var int
	 */
	const DEFAULT_DATE_FORMAT = 1;

	/**
	 * Defaut number format to us number
	 * @var int
	 */
	const DEFAULT_NUMBER_FORMAT = 3;

	/**
	 * Widget Preference name
	 * @var string
	 */
	const PREFERENCE_WIDGETS = 'hive-widgets';

	/**
	 * Widget Column Preferences
	 * @var string
	 */
	const PREFERENCE_DASHBOARD_LAYOUT = 'hive-dash-layout';
		
	/**
	 * Custom Mail Box
	 * @var string
	 */
	const CUSTOM_MAILBOX = 'user-mailbox';
	
	/**
	 * List of User Attached Mail Boxes
	 * @var array
	 */
	protected $mailboxes = null;
	
	
	/**
	 * User Authorized Groups
	 */
	public function group() {
		return $this->getPrefs('grouping');
	}

	/**
	 * Load all open user tasks
	 * @param array $fragments Additionnal search criteria
	 * @return array
	 */
	public function tasks(array $fragments = null,$limit = 10) {

		$finder = new \Shama\Task();
		$fragments[] = new \Fox\Dao\SqlFragment('assigned_to = ? AND status != ?',
							array($this->idusr,\Shama\Task::STATUS_CLOSED));
							
		$result = $finder->find(\Fox\Dao\SqlFragment::combine($fragments),
								array('duedate' => 'DESC'),
								null,
								$limit);
		return $result;
	}
	
	/**
	 * Apps user's selection limits.
	 *
	 * @see \Fox\User::createSelectionLimits()
	 */
	protected function createSelectionLimits() {
		$limits = array();
		if(!\Fox\Authorization\Manager::check(Ressource::AUTH_STATUS_CAN_VALID))
		{
			$data = array(Ressource::STATUS_NEW,Ressource::STATUS_VALIDATED);
			$limits[User::LIMIT_STATUS] = new \Fox\Dao\SqlFragment('%field$ IN (?)',array(explode(',', $data)),array(Connection::PARAM_STR_ARRAY));
		}

		return $limits;
	}
	
	/**
	 * User assigned groups (return result has an array)
	 */
	public function groups() {
		$groups = $this->group();
		if(empty($groups)) {
			return array();
		} else {
			return explode(',',$this->getPrefs('grouping')) ;
		}		
	}
	
	/**
	 * 
	 * Find and return user cloud name space
	 * 
	 * @return string
	 */
	public function cloudName() {
		$cloudname = $this->cloudname;
		if(empty($cloudname)) 
		{
			$cloudname = $this->usrnm;
		}
		$cloudname = preg_replace("/[^a-zA-Z0-9-]/",'_',$cloudname);
		return $cloudname;
	}
	
	/**
	 * 
	 * Check if the user is already connected to linked in
	 * @return bool
	 */
	public function alreadyConnectedToLinked() {
		// 1. Check if there is a secure token for the user account
		$token = \User::current()->getPrefs('linkedin-json-token',null,false,true);
		if(empty($token)) {
			return false;
		}
		$token = json_decode($token);
		$_SESSION['linkedin-access_token'] = $token->access_token; // guard this! 
	    $_SESSION['linkedin-expires_in']   = $token->expires_in; // relative time (in seconds)
	    $_SESSION['linkedin-expires_at']   = time() + $_SESSION['linkedin-expires_in']; // absolute time
		if ((empty($_SESSION['linkedin-expires_at'])) || (time() > $_SESSION['linkedin-expires_at'])) {
			// Token is no more valid
			$_SESSION['linkedin-access_token'] = null;
			return false;
		}
		return true;
	}
	
	/**
	 * 
	 * Widgets Are stored has a json string in the "hive-widgets" preference
	 * 
	 * @return array|false if no widget where setup 
	 */
	public function widgets() {
	
		$widgetList = null;
		$prefs = $this->getPrefs(self::PREFERENCE_WIDGETS);
		if(!empty($prefs)) {
			$widgets = json_decode($prefs,true);
			if(is_array($widgets) && count($widgets) > 0) {
				// Load Widget in the object from the DB
				foreach($widgets as $widget) {
					if(isset($widgetList[$widget['column']][$widget['position']])) {
						$widgetList[$widget['column']][] = $widget;
					} else {
						$widgetList[$widget['column']][$widget['position']] = $widget;
					}
					
				}
			}
		}
		
		return $widgetList;
	}
	
	/**
	 * 
	 * Widgets Are stored has a json string in the "hive-widgets" preference
	 * 
	 * @return array|false if no layout has been set
	 */
	public function dashboardLayout($value = null) {
		if(!empty($value)) {
			$this->setPrefs(self::PREFERENCE_DASHBOARD_LAYOUT,$value);
			return $value;
		}
		$layout = null;
		$prefs = $this->getPrefs(self::PREFERENCE_DASHBOARD_LAYOUT);
		if(!empty($prefs)) {
			$layout = json_decode($prefs,true);
		}
		return $layout;
	}	
	/**
	 * Load user attached mailers
	 * @return array
	 */
	public function personalMailers() {
		if(empty($this->mailboxes)) {
			// First Look up into shared mailbox list
			$query = Fox\Dao::infos(\Orx\User\Shared\MailBox\Item::className())
								->handle()->createQueryBuilder()
								->select('idusr','boxid')
								->from('user_shared_mailboxes','s');
			$groups = $this->groups();
			if(count($groups) > 0) {
				$fragment = new SqlFragment('(shared_id = ? AND shared_reference = ?) OR (shared_id IN(?) AND shared_reference = ?)',
										array($this->idusr,\Orx\User\Shared\MailBox\Item::USER_REFERENCE,
											$groups,\Orx\User\Shared\MailBox\Item::USER_GROUP_REFERENCE),
										array(Type::INTEGER,Type::INTEGER,Connection::PARAM_INT_ARRAY,Type::INTEGER));
			} else {
				$fragment = new SqlFragment('shared_id = ? AND shared_reference = ?',
										array($this->idusr,\Orx\User\Shared\MailBox\Item::USER_REFERENCE));
			}
			$sharedMailBoxes = $fragment->pushIn($query)->execute()->fetchAll(PDO::FETCH_ASSOC);
			if(count($sharedMailBoxes) > 0) {
				foreach($sharedMailBoxes as $sharedData) {
					$boxes[] = $sharedData['boxid'];
					$users[] = $sharedData['idusr'];
					$links[$sharedData['idusr'].':'.$sharedData['boxid']] = true;
				}
				$users[] =$this->getId();
				$mailboxes = Fox\Dao::finder(\Orx\User\MailBox::className())
					->where('idusr IN (?)',array($users),array(Connection::PARAM_INT_ARRAY))
					->find();
				foreach($mailboxes as $mailbox) {
					if($mailbox->idusr != $this->idusr) {
						// Need to check it the user has access to this mailbox
						$inlineid = $mailbox->idusr.':'.$mailbox->boxid;
						if(!isset($links[$inlineid])) {
							continue;
						}
						$mailbox->shared = true;
					}
					$this->mailboxes[] = $mailbox;
				}
			} else {
				$this->mailboxes = Fox\Dao::finder(\Orx\User\MailBox::className())
				->where('idusr = ?',array($this->getId()))
				->find();
			}
		}
		return $this->mailboxes;
	}
	
	/**
	 * Launch Mailer Synchronization
	 * @return bool
	 */
	public function synchronizeMailers($force = false) {
		$synchronization = array();
		foreach($this->personalMailers() as $mailer) {
			if($mailer->disable) {
				\Fox\Message::Warning(Msg(\Orx\Mailer\Messages::BUNDLE,
								\Orx\Mailer\Messages::WARNING_DISABLE_MAILBOX,
								$mailer->email));
			} else {
				/* @var $mailer \Orx\User\MailBox */
				$synchronization[] = $mailer->synchronize($force);
			}
		}
		return $synchronization;
	}
	
	/**
	 * Count User Messages that are in a specify statuses
	 * @param array|int $statuses
	 * @return int
	 */
	public function countMessagesInStatus($statuses) {
		if(!is_array($statuses)) {
			$statuses = array($statuses);
		}
		$query = \Fox\Dao::infos(\Orx\Mailer\MailBox\Message::className())
			->handle()->createQueryBuilder()
			->select('COUNT(messageid)')
			->from('messages','t');
		$fragment = new \Fox\Dao\SqlFragment('idusr = ? AND status IN (?) AND loekz = ?',
					array($this->idusr,$statuses,0),
					array(Type::INTEGER,Connection::PARAM_INT_ARRAY,Type::INTEGER));
		return $fragment->pushIn($query)->execute()->fetchColumn();
	}
}
/*
\Fox\Object\Links::add(\Fox\Dao::link(\Orx\Mailer\Mailbox\Message\Excluding\Rule::className(),\Orx\Mailer\Mailbox\Message\Excluding\Rule::LINK_USER)
->to(User::className(), User::LINK_MAILBOX_EXCLUDING_RULES)
->on('idusr')
);
*/